package com.ybt.channel.manager;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;

import com.ybt.channel.identify.IServiceIdentify;
import com.ybt.configration.IYBTConfigration;
import com.ybt.configration.YBTConfigration;
import com.ybt.configration.YBTRuntimeConfiguration;
import com.ybt.pub.XmlUtil;

public class ChannelManager {
    private static String CONFIG_DIR = "channel"
    + File.separator + "channel.xml";
    private volatile static ChannelManager manager;
    private Map<String, ChannelEntry> configs;
    private ChannelManager(){
        configs = new HashMap<String, ChannelEntry>();
        
        CONFIG_DIR = YBTConfigration.getInstance().getProperty(
                IYBTConfigration.WORKFLOW_DEPLOY_PATH)
                + File.separator + CONFIG_DIR;

        loadFromLocal();
    }
    public static ChannelManager getInstance(){
        if(manager == null){
            synchronized(ChannelManager.class){
                if(manager == null){
                    manager = new ChannelManager();
                }
            }
        }
        return manager;
    }
    
    public String getChannelWorkflow(String name){
        ChannelEntry entry = configs.get(name);
        if(entry==null){
            throw new RuntimeException("unsupport channel name, name is = " + name);
        }
        return entry.workflow;
    }

    public String getChannelByReqProtocol(String reqProtocol){
        for(ChannelEntry entry : configs.values()){
            if(reqProtocol.equals(entry.reqProcotol)){
                return entry.name;
            }
        }
        return null;
    }

    public String getRequestProtocol(String name){
        ChannelEntry entry = configs.get(name);
        if(entry==null){
            throw new RuntimeException("unsupport channel name, name is = " + name);
        }
        return entry.reqProcotol;
    }
    
    public String getResponseProtocol(String name){
        ChannelEntry entry = configs.get(name);
        if(entry==null){
            throw new RuntimeException("unsupport channel name, name is = " + name);
        }
        return entry.respProcotol;
    }
    
    private void loadFromLocal() {

        File file = new File(CONFIG_DIR);
        if (!file.exists()) {
            throw new RuntimeException("can't find the configration file : "
                    + CONFIG_DIR);
        }

        try {
            Document doc = XmlUtil.loadXml(CONFIG_DIR,
                    YBTRuntimeConfiguration.getInstance()
                            .getConfigFileCharset());
            List<Element> tasks = doc.getRootElement().elements();
            for (Element et : tasks) {
                String name = et.attributeValue("name");
                ChannelEntry entry =new ChannelEntry(name);
                
                String workflow = et.element("workflow").getTextTrim();
                entry.workflow = workflow;
                
                List<Element> ps = et.elements("protocol");
                for (Element p : ps) {
                    String type = p.attributeValue("type");
                    if("request".equals(type)){
                        entry.reqProcotol = p.getTextTrim();
                    }else{
                        entry.respProcotol = p.getTextTrim();
                    }
                }
                
                configs.put(name, entry);
            }
        } catch (Exception e) {
            throw new RuntimeException("parse configration file error : "
                    + CONFIG_DIR, e);
        }
    }
    
    class ChannelEntry{
        String name;
        String workflow;
        String reqProcotol;
        String respProcotol;
        
        public ChannelEntry(String name) {
            super();
            this.name = name;
        }
    }

}
